package com.kexio.auth.dto;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

/**
 * 用户权限信息DTO
 * 
 * 封装用户的完整权限信息，包括基础信息、角色、权限、菜单和数据权限范围。
 * 用于缓存和权限验证，是权限框架的核心数据结构。
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserAuthInfo implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    // ==================== 基础信息 ====================
    
    /**
     * 用户ID
     */
    private String userId;
    
    /**
     * 租户ID
     */
    private String tenantId;
    
    /**
     * 用户名
     */
    private String username;
    
    /**
     * 昵称
     */
    private String nickname;
    
    /**
     * 部门ID
     */
    private String deptId;
    
    /**
     * 部门名称
     */
    private String deptName;
    
    /**
     * 用户状态：1-启用，0-禁用
     */
    private Integer status;
    
    /**
     * 是否锁定
     */
    private Boolean isLocked;
    
    /**
     * 权限版本号（用于缓存一致性验证）
     */
    private Long permVersion;
    
    /**
     * 最后登录时间
     */
    private LocalDateTime lastLoginTime;
    
    // ==================== 权限信息 ====================
    
    /**
     * 用户角色列表
     */
    private List<RoleInfo> roles;
    
    /**
     * 用户权限集合（扁平化，便于快速检查）
     */
    private Set<String> permissions;
    
    /**
     * 用户可见菜单列表
     */
    private List<MenuInfo> menus;
    
    /**
     * 数据权限范围
     */
    private DataScopeInfo dataScope;
    
    // ==================== 会话信息 ====================
    
    /**
     * 会话ID
     */
    private String sessionId;
    
    /**
     * JWT Token ID
     */
    @JsonIgnore
    private String tokenId;
    
    /**
     * Token过期时间
     */
    private LocalDateTime tokenExpireTime;
    
    /**
     * 登录IP
     */
    private String loginIp;
    
    /**
     * 登录设备信息
     */
    private String deviceInfo;
    
    
    // ==================== 便捷方法 ====================
    
    /**
     * 判断用户是否有效（未禁用且未锁定）
     */
    @JsonIgnore
    public boolean isValid() {
        return status != null && status == 1 && (isLocked == null || !isLocked);
    }
    
    /**
     * 判断是否超级管理员（支持多种角色代码格式）
     */
    @JsonIgnore
    public boolean isSuperAdmin() {
        if (roles == null) return false;
        return roles.stream().anyMatch(role -> {
            String roleCode = role.getRoleCode();
            return "SUPER_ADMIN".equals(roleCode) ||
                   "role_super_admin".equals(roleCode) ||
                   "super_admin".equals(roleCode) ||
                   "ROLE_SUPER_ADMIN".equals(roleCode);
        });
    }
    
    /**
     * 判断是否拥有指定权限
     */
    @JsonIgnore
    public boolean hasPermission(String permission) {
        if (isSuperAdmin()) return true;
        return permissions != null && permissions.contains(permission);
    }
    
    /**
     * 判断是否拥有指定角色
     */
    @JsonIgnore
    public boolean hasRole(String roleCode) {
        if (roles == null) return false;
        return roles.stream().anyMatch(role -> roleCode.equals(role.getRoleCode()));
    }
    
    // ==================== Getter/Setter ====================
    
    public String getUserId() { return userId; }
    public void setUserId(String userId) { this.userId = userId; }
    public String getTenantId() { return tenantId; }
    public void setTenantId(String tenantId) { this.tenantId = tenantId; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getNickname() { return nickname; }
    public void setNickname(String nickname) { this.nickname = nickname; }
    public String getDeptId() { return deptId; }
    public void setDeptId(String deptId) { this.deptId = deptId; }
    public String getDeptName() { return deptName; }
    public void setDeptName(String deptName) { this.deptName = deptName; }
    public Integer getStatus() { return status; }
    public void setStatus(Integer status) { this.status = status; }
    public Boolean getIsLocked() { return isLocked; }
    public void setIsLocked(Boolean isLocked) { this.isLocked = isLocked; }
    public Long getPermVersion() { return permVersion; }
    public void setPermVersion(Long permVersion) { this.permVersion = permVersion; }
    public LocalDateTime getLastLoginTime() { return lastLoginTime; }
    public void setLastLoginTime(LocalDateTime lastLoginTime) { this.lastLoginTime = lastLoginTime; }
    public List<RoleInfo> getRoles() { return roles; }
    public void setRoles(List<RoleInfo> roles) { this.roles = roles; }
    public Set<String> getPermissions() { return permissions; }
    public void setPermissions(Set<String> permissions) { this.permissions = permissions; }
    public List<MenuInfo> getMenus() { return menus; }
    public void setMenus(List<MenuInfo> menus) { this.menus = menus; }
    public DataScopeInfo getDataScope() { return dataScope; }
    public void setDataScope(DataScopeInfo dataScope) { this.dataScope = dataScope; }
    public String getSessionId() { return sessionId; }
    public void setSessionId(String sessionId) { this.sessionId = sessionId; }
    public String getTokenId() { return tokenId; }
    public void setTokenId(String tokenId) { this.tokenId = tokenId; }
    public LocalDateTime getTokenExpireTime() { return tokenExpireTime; }
    public void setTokenExpireTime(LocalDateTime tokenExpireTime) { this.tokenExpireTime = tokenExpireTime; }
    public String getLoginIp() { return loginIp; }
    public void setLoginIp(String loginIp) { this.loginIp = loginIp; }
    public String getDeviceInfo() { return deviceInfo; }
    public void setDeviceInfo(String deviceInfo) { this.deviceInfo = deviceInfo; }
}
